TNDVI – Transformed Normalized Difference Vegetation Index
TNDVI (Transformed NDVI) is a non-linear transformation of NDVI designed to stabilize variance,
linearize the relationship with vegetation parameters, and enhance contrast in medium–high vegetation
cover. It is often used as a refined version of NDVI for biomass and canopy density analyses.
1. Concept & Equation of TNDVI
TNDVI is computed by applying a square-root transformation to NDVI, after adding a constant
(commonly 0.5) to shift the range towards positive values. This reduces the impact of noise in
low NDVI values and improves the correlation with vegetation biophysical parameters.
Core Equation
NDVI = (NIR − Red) / (NIR + Red)
TNDVI = √(NDVI + 0.5)
Where:
NIR: Near Infrared reflectance (e.g., 0.8 µm band)
Red: Red reflectance (e.g., 0.66 µm band)
Type: Vegetation IndexBased on NDVINon-linear transformation
Typical Value Ranges
TNDVI
Interpretation (approx.)
< 0.5
Bare soil, urban surfaces, very sparse vegetation
0.5 – 0.7
Moderate vegetation, mixed covers, shrubs and grasslands
> 0.7
Dense and healthy vegetation (croplands, forests)
Key Applications
Refined vegetation monitoring where NDVI saturates
Biomass and canopy density analysis
Change detection in agricultural and forest areas
Complementing NDVI in statistical and modeling workflows
2. Data & Bands for TNDVI
Common Sensors & Bands
Sentinel-2 (ESA) – 10 m
Red: B4 (~665 nm)
NIR: B8 (~842 nm)
Landsat 8/9 OLI – 30 m
Red: B4
NIR: B5
Good Practice
Use atmospherically corrected surface reflectance products.
Filter out cloudy scenes using cloud masks or cloud percentage thresholds.
Clip to the area of interest (AOI) to reduce processing time.
Example Workflows
Time-series analysis of TNDVI for crop monitoring.
Comparing NDVI and TNDVI for dense vegetation areas.
Integrating TNDVI into regression models for biomass estimation.
3. Google Earth Engine code for TNDVI (Sentinel-2)
This script computes NDVI first, then applies the transformation
TNDVI = sqrt(NDVI + 0.5) for a user-drawn AOI using Sentinel-2 Surface Reflectance data.
// -------------------------------------------------------
// TNDVI from Sentinel-2 Surface Reflectance
// Author: Start4IT (example template)
// -------------------------------------------------------
// 1) Define Area of Interest (AOI)
// Draw a polygon or rectangle on the map and name it "geometry" (default in GEE).
var roi = geometry;
// 2) Set time range
var startDate = '2023-01-01';
var endDate = '2023-12-31';
// 3) Load Sentinel-2 SR collection and filter
var s2 = ee.ImageCollection('COPERNICUS/S2_SR')
.filterBounds(roi)
.filterDate(startDate, endDate)
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))
.select(['B4','B8']); // Red, NIR
// 4) Create a median composite and clip to AOI
var s2_median = s2.median().clip(roi);
// 5) Compute NDVI
// NDVI = (NIR - Red) / (NIR + Red)
var ndvi = s2_median.normalizedDifference(['B8','B4']).rename('NDVI');
// 6) Compute TNDVI
// TNDVI = sqrt(NDVI + 0.5)
var tndvi = ndvi.add(0.5).sqrt().rename('TNDVI');
// 7) Visualization parameters for TNDVI
var tndviVis = {
min: 0.3,
max: 1.0,
palette: [
'#440154', // low
'#3b528b',
'#21908c',
'#5dc963',
'#fde725' // high
]
};
// 8) Center the map and add layers
Map.centerObject(roi, 10);
Map.addLayer(tndvi, tndviVis, 'TNDVI (Sentinel-2)', true);
// Optional: Add a true color background
var s2_rgb = ee.ImageCollection('COPERNICUS/S2_SR')
.filterBounds(roi)
.filterDate(startDate, endDate)
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))
.select(['B4','B3','B2']) // Red, Green, Blue
.median()
.clip(roi);
Map.addLayer(s2_rgb, {min:0, max:3000}, 'True Color (RGB)', false);
// 9) Export TNDVI as GeoTIFF to Google Drive
Export.image.toDrive({
image: tndvi,
description: 'TNDVI_Export',
fileNamePrefix: 'TNDVI_Export',
folder: 'GEE_TNDVI',
region: roi,
scale: 10,
crs: 'EPSG:4326',
maxPixels: 1e13
});